package com.ssy.lingxi.contract.esign.api;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.ssy.lingxi.contract.esign.EsignProperties;
import com.ssy.lingxi.contract.esign.constant.RequestMethod;
import com.ssy.lingxi.contract.esign.exception.EsignException;
import com.ssy.lingxi.contract.esign.request.*;
import com.ssy.lingxi.contract.esign.response.*;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 签署服务API
 * @author yzc
 * @version 2.0.0
 * @date 2020/8/26
 */
public class SignFlow {

    private final AuthToken authToken;
    private final EsignProperties properties;

    public SignFlow(AuthToken authToken, EsignProperties properties) {
        this.authToken = authToken;
        this.properties = properties;
    }

    /**
     * 一步发起签署
     */
    public SignFlowResponse signFlowCreateOneStep(SignFlowCreateOneStepRequest request) throws EsignException {
        String resourcePath = "/api/v2/signflows/createFlowOneStep";
        RequestMethod method = RequestMethod.POST;

        Map<String, Object> paramMap = BeanUtil.beanToMap(request);

        EsignRequest esignRequest = new EsignRequest(method, resourcePath, paramMap, authToken, properties);
        String execute = EsignResource.execute(esignRequest);

        return JSONUtil.toBean(execute, SignFlowResponse.class);
    }


    //=============================签署流程=================================

    /**
     * 签署流程创建
     */
    public SignFlowResponse signFlowCreate(SignFlowCreateRequest request) throws EsignException {
        String resourcePath = "/v1/signflows";
        RequestMethod method = RequestMethod.POST;

        Map<String, Object> paramMap = BeanUtil.beanToMap(request);

        EsignRequest esignRequest = new EsignRequest(method, resourcePath, paramMap, authToken, properties);
        String execute = EsignResource.execute(esignRequest);

        return JSONUtil.toBean(execute, SignFlowResponse.class);
    }

    /**
     * 签署流程查询
     */
    public SignFlowDetailResponse signFlowDetail(String flowId) throws EsignException {
        String resourcePath = "/v1/signflows/{flowId}";
        RequestMethod method = RequestMethod.GET;

        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("flowId", flowId);

        EsignRequest esignRequest = new EsignRequest(method, resourcePath, paramMap, authToken, properties);
        String execute = EsignResource.execute(esignRequest);

        return JSONUtil.toBean(execute, SignFlowDetailResponse.class);
    }

    /**
     * 签署流程开启
     */
    public void signFlowStart(String flowId) throws EsignException {
        String resourcePath = "/v1/signflows/{flowId}/start";
        RequestMethod method = RequestMethod.PUT;

        Map<String, List<String>> headerMap = new HashMap<>();
        headerMap.put("Content-Type", Collections.singletonList("application/json"));

        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("flowId", flowId);

        EsignRequest esignRequest = new EsignRequest(method, resourcePath, headerMap, paramMap, authToken, properties);
        String execute = EsignResource.execute(esignRequest);
    }

    /**
     * 签署流程撤销
     */
    public void signFlowRevoke(SignFlowRevokeRequest request) throws EsignException {
        String resourcePath = "/v1/signflows/{flowId}/revoke";
        RequestMethod method = RequestMethod.PUT;

        Map<String, List<String>> headerMap = new HashMap<>();
        headerMap.put("Content-Type", Collections.singletonList("application/json"));

        Map<String, Object> paramMap = BeanUtil.beanToMap(request);

        EsignRequest esignRequest = new EsignRequest(method, resourcePath, headerMap, paramMap, authToken, properties);
        String execute = EsignResource.execute(esignRequest);
    }

    /**
     * 签署流程归档
     */
    public void signFlowArchive(String flowId) throws EsignException {
        String resourcePath = "/v1/signflows/{flowId}/archive";
        RequestMethod method = RequestMethod.PUT;

        Map<String, List<String>> headerMap = new HashMap<>();
        headerMap.put("Content-Type", Collections.singletonList("application/json"));

        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("flowId", flowId);

        EsignRequest esignRequest = new EsignRequest(method, resourcePath, headerMap, paramMap, authToken, properties);
        String execute = EsignResource.execute(esignRequest);
    }


    //=============================流程文档=================================

    /**
     * 流程文档添加
     */
    public void signFlowDocumentsAdd(SignFlowDocumentsAddRequest request) throws EsignException {
        String resourcePath = "/v1/signflows/{flowId}/documents";
        RequestMethod method = RequestMethod.POST;

        Map<String, Object> paramMap = BeanUtil.beanToMap(request);

        EsignRequest esignRequest = new EsignRequest(method, resourcePath, paramMap, authToken, properties);
        String execute = EsignResource.execute(esignRequest);
    }

    /**
     * 流程文档下载
     */
    public SignFlowDocResponse signFlowDocumentsDownload(String flowId) throws EsignException {
        String resourcePath = "/v1/signflows/{flowId}/documents";
        RequestMethod method = RequestMethod.GET;

        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("flowId", flowId);

        EsignRequest esignRequest = new EsignRequest(method, resourcePath, paramMap, authToken, properties);
        String execute = EsignResource.execute(esignRequest);

        return JSONUtil.toBean(execute, SignFlowDocResponse.class);
    }


    //=============================流程附件=================================

    /**
     * 流程附件添加
     */
    public void signFlowAttachmentsAdd(SignflowsAttachmentsAddRequest request) throws EsignException {
        String resourcePath = "/v1/signflows/{flowId}/attachments";
        RequestMethod method = RequestMethod.POST;

        Map<String, Object> paramMap = BeanUtil.beanToMap(request);

        EsignRequest esignRequest = new EsignRequest(method, resourcePath, paramMap, authToken, properties);
        String execute = EsignResource.execute(esignRequest);
    }


    //=============================流程签署区=================================

    /**
     * 添加平台自动盖章签署区
     */
    public SignFieldPlatformResponse signFieldPlatform(SignFieldPlatformRequest request) throws EsignException {
        String resourcePath = "/v1/signflows/{flowId}/signfields/platformSign";
        RequestMethod method = RequestMethod.POST;

        Map<String, Object> paramMap = BeanUtil.beanToMap(request);

        EsignRequest esignRequest = new EsignRequest(method, resourcePath, paramMap, authToken, properties);
        String execute = EsignResource.execute(esignRequest);

        return JSONUtil.toBean(execute, SignFieldPlatformResponse.class);
    }

    /**
     * 添加签署方自动盖章签署区
     */
    public SignFieldAutoResponse signFieldAuto(SignFieldAutoRequest request) throws EsignException {
        String resourcePath = "/v1/signflows/{flowId}/signfields/autoSign";
        RequestMethod method = RequestMethod.POST;

        Map<String, Object> paramMap = BeanUtil.beanToMap(request);

        EsignRequest esignRequest = new EsignRequest(method, resourcePath, paramMap, authToken, properties);
        String execute = EsignResource.execute(esignRequest);

        return JSONUtil.toBean(execute, SignFieldAutoResponse.class);
    }

    /**
     * 添加手动盖章签署区
     */
    public SignFieldAutoResponse signFieldHandSign(SignFieldHandSignRequest request) throws EsignException {
        String resourcePath = "/v1/signflows/{flowId}/signfields/handSign";
        RequestMethod method = RequestMethod.POST;

        Map<String, Object> paramMap = BeanUtil.beanToMap(request);

        EsignRequest esignRequest = new EsignRequest(method, resourcePath, paramMap, authToken, properties);
        String execute = EsignResource.execute(esignRequest);

        return JSONUtil.toBean(execute, SignFieldAutoResponse.class);
    }

    /**
     * 查询签署区列表
     */
    public SignFieldDetailResponse signFieldDetail(SignFieldDetailRequest request) throws EsignException {
        String resourcePath = "/v1/signflows/{flowId}/signfields";
        RequestMethod method = RequestMethod.GET;

        Map<String, Object> paramMap = BeanUtil.beanToMap(request);

        EsignRequest esignRequest = new EsignRequest(method, resourcePath, paramMap, authToken, properties);
        String execute = EsignResource.execute(esignRequest);

        return JSONUtil.toBean(execute, SignFieldDetailResponse.class);
    }

    //=============================流程签署人=================================

    /**
     * 获取签署地址
     */
    public ExecuteUrlResponse executeUrl(ExecuteUrlRequest request) throws EsignException {
        String resourcePath = "/v1/signflows/{flowId}/executeUrl";
        RequestMethod method = RequestMethod.GET;

        Map<String, Object> paramMap = BeanUtil.beanToMap(request);

        EsignRequest esignRequest = new EsignRequest(method, resourcePath, paramMap, authToken, properties);
        String execute = EsignResource.execute(esignRequest);

        return JSONUtil.toBean(execute, ExecuteUrlResponse.class);
    }
}
